﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.Pex.Framework;



namespace Benchmarks.McMinnThesisBen
{
    [TestClass, PexClass(typeof(AnomalyDetector))]    
    public class AnomalyDetector
    {
        static int MAX_ELEMENTS = 4;
        int[] vibration;
        bool bufferFull;
        int ptr;
        
        public AnomalyDetector()
        {
            vibration = new int[MAX_ELEMENTS];
            bufferFull = false;
            ptr = 0;            
        }

        public void AddData(int currentVibration)
        {
            vibration[ptr] = currentVibration;
            ptr++;
            if (ptr == MAX_ELEMENTS)
            {
                ptr = 0;
                bufferFull = true;
            }
        }

        public bool NormalLimits()
        {
            if (bufferFull)
            {
                int total = 0, mean = 0,
                variance = 0, last_element = 0;
                int i, j;
                int cur_pos = ptr - 1;
                if (cur_pos == -1)
                {
                    cur_pos = MAX_ELEMENTS - 1;
                }
                for (i = 0; i < MAX_ELEMENTS; i++)
                {
                    if (i != cur_pos)
                    {
                        total += vibration[i];
                    }
                }
                mean = total / (MAX_ELEMENTS - 1);
                total = 0;
                for (j = 0; j < MAX_ELEMENTS; j++)
                {
                    if (j != cur_pos)
                    {
                        total += (vibration[j] - mean) *
                        (vibration[j] - mean);
                    }
                }
                variance = total / MAX_ELEMENTS - 1;
                last_element = (vibration[cur_pos] - mean) *
                                (vibration[cur_pos] - mean);
                if (last_element > variance)
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
            else
            {
                return true;
            }
        }

        public void Reset()
        {
            bufferFull = false;
            ptr = 0;
        }

        //README of running these test methods with Pex
        //For each METHODNAME, run with C:\pex\bin\Debug>Pex Benchmarks.dll /mf:METHODNAME
        // adding /fte outputs all generated tests


        //using 18 runs to achieve 33/35
        //[PexMethod(MaxRuns = 60, MaxConditions = int.MaxValue, MaxRunsWithoutNewTests = int.MaxValue)]        
        //public void TestAnomalyDetectorFitness(
        //                    int[] modifiers, int[] vibrates) 
        //{
        //    TestAnomalyDetector(modifiers, vibrates);
        //}

        ////using 30 runs to achieve 33/35
        //[PexMethod(MaxRuns = 60, MaxConditions = int.MaxValue, MaxRunsWithoutNewTests = int.MaxValue)]        
        //public void TestAnomalyDetectorDefault(
        //                    int[] modifiers, int[] vibrates)
        //{
        //    TestAnomalyDetector(modifiers, vibrates);
        //}
    
        //private void TestAnomalyDetector(
        //                    int[] modifiers, int[] vibrates)
        //{
        //    PexAssume.IsTrue(modifiers != null);
        //    PexAssume.IsTrue(vibrates != null);
        //    PexAssume.IsTrue(modifiers.Length == vibrates.Length);

        //    AnomalyDetector c  = new AnomalyDetector();
        //    for (int i = 0; i <= (modifiers.Length - 1); i++)
        //    {
        //        //switch (modifiers[i])
        //        //{
        //        //    case 0:
        //        if (modifiers[i] == 0) 
        //                c.AddData(vibrates[i]);
        //                //break;                    
        //            //default:
        //        else         
        //            c.Reset();
        //            //    break;
        //        //}
        //    }
        //    c.NormalLimits();
        //}
    }
}
